package cn.passlink.www.Controller;
import cn.passlink.www.Enity.sysUser;
import cn.passlink.www.Mapper.sysUserDao;
import cn.passlink.www.Server.AuthServer;
import cn.passlink.www.Utils.*;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.awt.image.BufferedImage;
import java.util.Date;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

@RestController
@Slf4j
@RequestMapping("/auth")
public class AuthController {
    @Autowired
    private DefaultKaptcha defaultKaptcha;

    @Autowired
    public RedisTemplate redisTemplate;

    @Autowired
    private JavaMailSender mailSender;

    @Resource
    private AuthServer authServer;

    @Autowired
    sysUserDao sysUserDao;

    //登陆验证
    @PostMapping("/login")
    public Map<String, Object> login(@RequestBody Map<String, Object> requestData) {
//检测字段
        String[] keys = {"username", "password", "captcha"};
        if (!ReqDataCheck.ReqDataCheckKeys(requestData, keys)) {
            log.error("请求数据错误---");
            return JsonUtils.resultJson(403, "请求数据错误");
        }
        String username = (String) requestData.getOrDefault("username", "");
        String password = (String) requestData.getOrDefault("password", "");
        String captcha = (String) requestData.get("captcha");

//图片验证码验证
        if (!redisTemplate.hasKey("capText")) {
            log.error("验证码不存在---");
            return JsonUtils.resultJson(403, "验证码错误！");
        }
//        过期
        Long expire = redisTemplate.getExpire("capText"); // 获取键的剩余过期时间（以秒为单位）
        if (expire != null && expire <= 0) {
            log.error("验证码已过期---");
            redisTemplate.delete("capText");
            return JsonUtils.resultJson(403, "验证码已过期");
        }
//        不对应
        if (!redisTemplate.opsForValue().get("capText").equals(captcha)) {
            redisTemplate.delete("capText");
            log.error("验证码匹配错误---");
            return JsonUtils.resultJson(403, "验证码错误！！！");
        }
//        验证一次删一次
        redisTemplate.delete("capText");
        log.info("验证码删除---");
//        检测是否符合要求
        if (username.length() < 6 || username.length() > 20 || password.length() < 8 || password.length() > 200) {
            log.error("用户或密码长度错误---");
            return JsonUtils.resultJson(403, "用户或密码错误");
        }

        return authServer.loginAuth(username, password);

    }

    //注册
    @PostMapping("/register")
    public Map<String, Object> register(@RequestBody Map<String, Object> requestData) {
//       检测字段
        String[] keys = {"username", "password", "emailCode"};
        if (!ReqDataCheck.ReqDataCheckKeys(requestData, keys)) {
            log.error("请求数据字段缺失---");
            return JsonUtils.resultJson(403, "请求数据错误");
        }
//        读取Email
        String email = (String) redisTemplate.opsForValue().get("reg_email");
        String username = (String) requestData.get("username");
        String password = (String) requestData.get("password");
        String emailCode = (String) requestData.get("emailCode");

        if (username.length() < 6 || username.length() > 20 || password.length() < 8 || password.length() > 200) {
            log.error("用户名或密码长度不符合要求---");
            return JsonUtils.resultJson(403, "用户名或密码非法！！！！");
        }
        //检查邮箱
        if (email == null || email.isEmpty()) {
            log.error("邮箱为空---");
            return JsonUtils.resultJson(500, "注册失败！！！");
        }
//不存在
        if (!redisTemplate.hasKey("code")) {
            log.error("邮箱验证码不存在---");
            return JsonUtils.resultJson(403, "请重新获取验证码");
        }
//        过期
        Long expire = redisTemplate.getExpire("code"); // 获取键的剩余过期时间（以秒为单位）
        if (expire != null && expire <= 0) {
            redisTemplate.delete("code");
            log.error("邮箱验证码已过期--");
            return JsonUtils.resultJson(403, "验证码已过期");
        }
//        不对应
        if (!redisTemplate.opsForValue().get("code").equals(emailCode)) {
            log.error("验证码错误--");
            return JsonUtils.resultJson(403, "验证码错误，请重新再试！！！");
        }

        System.out.println(email);
        redisTemplate.delete("reg_email");
        log.info("验证码删除--");
        return authServer.register(username, password, email);

    }

    //获取图片验证码
    @GetMapping("/captcha")
    public Map<String, Object> captcha() {
        // 生成验证码
        String capText = defaultKaptcha.createText();
        redisTemplate.opsForValue().set("capText", capText, 5, TimeUnit.MINUTES);
        log.info("图片验证码生成--");
        System.out.println(redisTemplate.opsForValue().get("capText"));
        // 生成验证码图片，并将其转换为字节数组
        BufferedImage bufferedImage = defaultKaptcha.createImage(capText);
        return CaptchaUtil.catchaImgCreator(bufferedImage);
    }


    //获取邮箱验证码
    @PostMapping("/emailCode")
    public Map<String, Object> emailCode(@RequestBody Map<String, Object> requestData) {
//       检测字段
        String[] keys = {"email", "captcha"};
        if (!ReqDataCheck.ReqDataCheckKeys(requestData, keys)) {
            log.error("请求数据错误--");
            return JsonUtils.resultJson(403, "请求数据错误");
        }

        String email = (String) requestData.get("email");
        String captcha = (String) requestData.get("captcha");
        if (email.length() > 50 || captcha.length() > 50) {
            log.error("邮箱错误--");
            return JsonUtils.resultJson(403, "你确定要注册？");
        }

        String regex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
        if (!Pattern.matches(regex, email) || email.length() < 5) {
            log.error("邮箱不合法");
            return JsonUtils.resultJson(403, "邮箱不合法！！！");
        }

        //            检查用户和邮箱是否已经存在
        sysUser user = sysUserDao.findByEmail(email);
        if (user != null) {
            log.error("用户已存在--");
            return JsonUtils.resultJson(403, "用户已存在，请使用其他名称或邮箱进行注册！！！");
        }
//图片验证码验证
        if (!redisTemplate.hasKey("capText")) {
            log.error("验证码不存在--");
            return JsonUtils.resultJson(403, "验证码错误！");
        }
//        过期
        Long expire1 = redisTemplate.getExpire("capText"); // 获取键的剩余过期时间（以秒为单位）
        if (expire1 != null && expire1 <= 0) {
            redisTemplate.delete("capText");
            log.error("验证码已过期");
            return JsonUtils.resultJson(403, "验证码已过期");
        }
//        不对应
        if (!redisTemplate.opsForValue().get("capText").equals(captcha)) {
            redisTemplate.delete("capText");
            log.error("验证码错误");
            return JsonUtils.resultJson(403, "验证码错误！！！");
        }
//        验证一次删一次
        redisTemplate.delete("capText");


//发送邮箱验证码
        Date nowDate = new Date();
        Long nowTime = nowDate.getTime();
        redisTemplate.opsForValue().set("reg_email", email, 10, TimeUnit.MINUTES);
// 存在，更新
        if (redisTemplate.hasKey("lastTime")) {
            String lastTimeStr = (String) redisTemplate.opsForValue().get("lastTime");
            Long lastTime = Long.parseLong(lastTimeStr);
            // 计算时间差（毫秒）
            long timeDiff = nowTime - lastTime;
            long secondsDiff = timeDiff / 1000;
            if (secondsDiff < 120) {
                log.error("请等待120秒后重试");
                return JsonUtils.resultJson(403, "请等待120秒后重试");
            }
        }
// 更新最新时间
        redisTemplate.opsForValue().set("lastTime", nowTime.toString());
//发送邮箱
        EmailUtils emailUtils = new EmailUtils(mailSender);
        String code = randomNum();
        redisTemplate.opsForValue().set("code", code, 5, TimeUnit.MINUTES);
        System.out.println(redisTemplate.opsForValue().get("code"));
        String html = "<div style=\"height: auto;width: 100vw;background-color: rgb(36, 36, 36);padding: 20px;\">\n" + "<img style=\"width: 80px;height: 80px;\" src=\"\" alt=\"passlink\"/>\n" + "<p style=\"color: yellow;font-size: 3.5em;\">PASSLINK.CN</p>\n" + "<div style=\"color: aliceblue;width: auto; margin: auto;\">\n" + "<p style=\"font-size: 2.5em;\">与世界连接</p>\n" + "<p style=\"text-align: center;font-size: 1.5em;\">欢迎注册 , 您的验证码为 : </p>\n" + "<p style=\"text-align: center;font-size: 2.5em;\"><a style=\"color: aliceblue;\" href=\"http://www.passlink.cn\">" + code + "</a></p>\n" + "</div>\n" + "</div>";
        return emailUtils.sendHtmlMail(email, "注册验证码", html);
    }


    //注销登录，把jwt加入黑名单
    @DeleteMapping("/logout")
    public Map<String, Object> logout() {

        return authServer.logout();
    }

    private String randomNum() {
        Random random = new Random();
        // 生成6位随机数字
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            int num = random.nextInt(10); // 生成0-9之间的随机数
            sb.append(num);
        }
        return sb.toString();
    }


}
